home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 4 / MacFormat n. 4 (Spain) / MacFormat 4.bin / La ciudad del ShareWare / Desarrollo / macgzip_03b2-src / unlzw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-09  |  9.0 KB  |  400 lines

  1. /* unlzw.c -- decompress files in LZW format.
  2.  * The code in this file is directly derived from the public domain 'compress'
  3.  * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
  4.  * Ken Turkowski, Dave Mack and Peter Jannesen.
  5.  *
  6.  * This is a temporary version which will be rewritten in some future version
  7.  * to accommodate in-memory decompression.
  8.  */
  9.  
  10. /*
  11.  * Modified:1993 by SPDsoft for MacGzip
  12.  *
  13.  */
  14.  
  15. #ifdef RCSID
  16. static char rcsid[] = "$Id: unlzw.c,v 0.15 1993/06/10 13:28:35 jloup Exp $";
  17. #endif
  18.  
  19. #include <sys/types.h>
  20.  
  21. #if defined(__MWERKS__) 
  22. #  include <stddef.h>
  23. #endif
  24.  
  25. #include "tailor.h"
  26.  
  27. #ifdef HAVE_UNISTD_H
  28. #  include <unistd.h>
  29. #endif
  30. #ifndef NO_FCNTL_H
  31. #  include <fcntl.h>
  32. #endif
  33.  
  34. #include "gzip.h"
  35. #include "lzw.h"
  36.  
  37. #include "MacErrors.h"
  38. #include "SPDProg.h"
  39. #include <signal.h>
  40. extern long tell(int fn);
  41.  
  42. typedef    unsigned char    char_type;
  43. typedef          long   code_int;
  44. typedef unsigned long     count_int;
  45. typedef unsigned short    count_short;
  46. typedef unsigned long     cmp_code_int;
  47.  
  48. #define MAXCODE(n)    (1L << (n))
  49.     
  50. #ifndef    REGISTERS
  51. #    define    REGISTERS    2
  52. #endif
  53. #define    REG1    
  54. #define    REG2    
  55. #define    REG3    
  56. #define    REG4    
  57. #define    REG5    
  58. #define    REG6    
  59. #define    REG7    
  60. #define    REG8    
  61. #define    REG9    
  62. #define    REG10
  63. #define    REG11    
  64. #define    REG12    
  65. #define    REG13
  66. #define    REG14
  67. #define    REG15
  68. #define    REG16
  69. #if REGISTERS >= 1
  70. #    undef    REG1
  71. #    define    REG1    register
  72. #endif
  73. #if REGISTERS >= 2
  74. #    undef    REG2
  75. #    define    REG2    register
  76. #endif
  77. #if REGISTERS >= 3
  78. #    undef    REG3
  79. #    define    REG3    register
  80. #endif
  81. #if REGISTERS >= 4
  82. #    undef    REG4
  83. #    define    REG4    register
  84. #endif
  85. #if REGISTERS >= 5
  86. #    undef    REG5
  87. #    define    REG5    register
  88. #endif
  89. #if REGISTERS >= 6
  90. #    undef    REG6
  91. #    define    REG6    register
  92. #endif
  93. #if REGISTERS >= 7
  94. #    undef    REG7
  95. #    define    REG7    register
  96. #endif
  97. #if REGISTERS >= 8
  98. #    undef    REG8
  99. #    define    REG8    register
  100. #endif
  101. #if REGISTERS >= 9
  102. #    undef    REG9
  103. #    define    REG9    register
  104. #endif
  105. #if REGISTERS >= 10
  106. #    undef    REG10
  107. #    define    REG10    register
  108. #endif
  109. #if REGISTERS >= 11
  110. #    undef    REG11
  111. #    define    REG11    register
  112. #endif
  113. #if REGISTERS >= 12
  114. #    undef    REG12
  115. #    define    REG12    register
  116. #endif
  117. #if REGISTERS >= 13
  118. #    undef    REG13
  119. #    define    REG13    register
  120. #endif
  121. #if REGISTERS >= 14
  122. #    undef    REG14
  123. #    define    REG14    register
  124. #endif
  125. #if REGISTERS >= 15
  126. #    undef    REG15
  127. #    define    REG15    register
  128. #endif
  129. #if REGISTERS >= 16
  130. #    undef    REG16
  131. #    define    REG16    register
  132. #endif
  133.     
  134. #ifndef    BYTEORDER
  135. #    define    BYTEORDER    0000
  136. #endif
  137.     
  138. #ifndef    NOALLIGN
  139. #    define    NOALLIGN    0
  140. #endif
  141.  
  142.  
  143. union    bytes {
  144.     long  word;
  145.     struct {
  146. #if BYTEORDER == 4321
  147.     char_type    b1;
  148.     char_type    b2;
  149.     char_type    b3;
  150.     char_type    b4;
  151. #else
  152. #if BYTEORDER == 1234
  153.     char_type    b4;
  154.     char_type    b3;
  155.     char_type    b2;
  156.     char_type    b1;
  157. #else
  158. #    undef    BYTEORDER
  159.     int  dummy;
  160. #endif
  161. #endif
  162.     } bytes;
  163. };
  164.  
  165. #if BYTEORDER == 4321 && NOALLIGN == 1
  166. #  define input(b,o,c,n,m){ \
  167.      (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \
  168.      (o) += (n); \
  169.    }
  170. #else
  171. #  define input(b,o,c,n,m){ \
  172.      REG1 char_type *p = &(b)[(o)>>3]; \
  173.      (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
  174.      ((long)(p[2])<<16))>>((o)&0x7))&(m); \
  175.      (o) += (n); \
  176.    }
  177. #endif
  178.  
  179. #ifndef MAXSEG_64K
  180.    /* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */
  181. #  define tab_prefixof(i) tab_prefix[i]
  182. #  define clear_tab_prefixof()    memzero(tab_prefix, 256);
  183. #else
  184.    /* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */
  185.    /* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd  codes */
  186.    ush *tab_prefix[2];
  187. #  define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1]
  188. #  define clear_tab_prefixof()    \
  189.       memzero(tab_prefix0, 128), \
  190.       memzero(tab_prefix1, 128);
  191. #endif
  192. #define de_stack        ((char_type *)(&d_buf[DIST_BUFSIZE-1]))
  193. #define tab_suffixof(i) tab_suffix[i]
  194.  
  195. int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */
  196.  
  197. /* ============================================================================
  198.  * Decompress in to out.  This routine adapts to the codes in the
  199.  * file building the "string" table on-the-fly; requiring no table to
  200.  * be stored in the compressed file.
  201.  * IN assertions: the buffer inbuf contains already the beginning of
  202.  *   the compressed data, from offsets iptr to insize-1 included.
  203.  *   The magic header has already been checked and skipped.
  204.  *   bytes_in and bytes_out have been initialized.
  205.  */
  206. int unlzw(in, out) 
  207.     int in, out;    /* input and output file descriptors */
  208. {
  209.     REG2   char_type  *stackp;
  210.     REG3   code_int   code;
  211.     REG4   int        finchar;
  212.     REG5   code_int   oldcode;
  213.     REG6   code_int   incode;
  214.     REG7   long       inbits;
  215.     REG8   long       posbits;
  216.     REG9   int        outpos;
  217. /*  REG10  int        insize; (global) */
  218.     REG11  unsigned   bitmask;
  219.     REG12  code_int   free_ent;
  220.     REG13  code_int   maxcode;
  221.     REG14  code_int   maxmaxcode;
  222.     REG15  int        n_bits;
  223.     REG16  long int        rsize;                 /* SPDsoft */
  224.     
  225. #ifdef MAXSEG_64K
  226.     tab_prefix[0] = tab_prefix0;
  227.     tab_prefix[1] = tab_prefix1;
  228. #endif
  229.     maxbits = get_byte();
  230.     block_mode = maxbits & BLOCK_MODE;
  231.     if ((maxbits & LZW_RESERVED) != 0) {
  232.     WARN((strerr, "%s: %s: warning, unknown flags 0x%x",
  233.           progname, ifname, maxbits & LZW_RESERVED));
  234.     }
  235.     maxbits &= BIT_MASK;
  236.     maxmaxcode = MAXCODE(maxbits);
  237.     
  238.     if (maxbits > BITS) {
  239.     sprintf(strerr,
  240.         "%s: compressed with %d bits, can only handle %d bits",
  241.         ifname, maxbits, BITS);
  242.     Calert(strerr);
  243.     exit_code = ERROR;
  244.     return ERROR;
  245.     }
  246.     rsize = insize;
  247.     maxcode = MAXCODE(n_bits = INIT_BITS)-1;
  248.     bitmask = (1<<n_bits)-1;
  249.     oldcode = -1;
  250.     finchar = 0;
  251.     outpos = 0;
  252.     posbits = inptr<<3;
  253.  
  254.     free_ent = ((block_mode) ? FIRST : 256);
  255.     
  256.     clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */
  257.     
  258.     for (code = 255 ; code >= 0 ; --code) {
  259.     tab_suffixof(code) = (char_type)code;
  260.     }
  261.     do {
  262.     REG1 int i;
  263.     int  e;
  264.     int  o;
  265.     
  266.     resetbuf:
  267.     
  268.       e = insize-(o = (posbits>>3));
  269.     
  270.     for (i = 0 ; i < e ; ++i) {
  271.         inbuf[i] = inbuf[i+o];
  272.     }
  273.     insize = e;
  274.     posbits = 0;
  275.     
  276.     if (insize < INBUF_EXTRA) {
  277.         if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) {
  278.         read_error();
  279.         }
  280.         
  281. #ifdef _SPD_PROG_
  282.     SPDNow=(unsigned long int)tell(in);
  283.     if(SPDSystemTask()) raise(SIGINT);
  284. #endif 
  285.  
  286.         insize +=  rsize;
  287.         bytes_in += (ulg)rsize;
  288.     }
  289.     inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : 
  290.           ((long)insize<<3)-(n_bits-1));
  291.     
  292.     while (inbits > posbits) {
  293.         if (free_ent > maxcode) {
  294.         posbits = ((posbits-1) +
  295.                ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
  296.         ++n_bits;
  297.         if (n_bits == maxbits) {
  298.             maxcode = maxmaxcode;
  299.         } else {
  300.             maxcode = MAXCODE(n_bits)-1;
  301.         }
  302.         bitmask = (1<<n_bits)-1;
  303.         goto resetbuf;
  304.         }
  305.         input(inbuf,posbits,code,n_bits,bitmask);
  306.         Tracev((stderr, "%d ", code));
  307.  
  308.         if (oldcode == -1) {
  309.         if (code >= 256) error("corrupt input.");
  310.         outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code));
  311.         continue;
  312.         }
  313.         if (code == CLEAR && block_mode) {
  314.         clear_tab_prefixof();
  315.         free_ent = FIRST - 1;
  316.         posbits = ((posbits-1) +
  317.                ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
  318.         maxcode = MAXCODE(n_bits = INIT_BITS)-1;
  319.         bitmask = (1<<n_bits)-1;
  320.         goto resetbuf;
  321.         }
  322.         incode = code;
  323.         stackp = de_stack;
  324.         
  325.         if (code >= free_ent) { /* Special case for KwKwK string. */
  326.         if (code > free_ent) {
  327. #ifdef DEBUG
  328.             char_type *p;
  329.  
  330.             posbits -= n_bits;
  331.             p = &inbuf[posbits>>3];
  332.             fprintf(stderr,
  333.                 "code:%ld free_ent:%ld n_bits:%d insize:%u\n",
  334.                 code, free_ent, n_bits, insize);
  335.             fprintf(stderr,
  336.                 "posbits:%ld inbuf:%02X %02X %02X %02X %02X\n",
  337.                 posbits, p[-1],p[0],p[1],p[2],p[3]);
  338. #endif
  339.             if (!test && outpos > 0) {
  340.             write_buf(out, (char*)outbuf, outpos);
  341.             bytes_out += (ulg)outpos;
  342.             }
  343.             error(to_stdout ? "corrupt input." :
  344.               "corrupt input. Use zcat to recover some data.");
  345.         }
  346.         *--stackp = (char_type)finchar;
  347.         code = oldcode;
  348.         }
  349.  
  350.         while ((cmp_code_int)code >= (cmp_code_int)256) {
  351.         /* Generate output characters in reverse order */
  352.         *--stackp = tab_suffixof(code);
  353.         code = tab_prefixof(code);
  354.         }
  355.         *--stackp =    (char_type)(finchar = tab_suffixof(code));
  356.         
  357.         /* And put them out in forward order */
  358.         {
  359.         REG1 int    i;
  360.         
  361.         if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) {
  362.             do {
  363.             if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos;
  364.  
  365.             if (i > 0) {
  366.                 memcpy(outbuf+outpos, stackp, i);
  367.                 outpos += i;
  368.             }
  369.             if (outpos >= OUTBUFSIZ) {
  370.                 if (!test) {
  371.                 write_buf(out, (char*)outbuf, outpos);
  372.                 bytes_out += (ulg)outpos;
  373.                 }
  374.                 outpos = 0;
  375.             }
  376.             stackp+= i;
  377.             } while ((i = (de_stack-stackp)) > 0);
  378.         } else {
  379.             memcpy(outbuf+outpos, stackp, i);
  380.             outpos += i;
  381.         }
  382.         }
  383.  
  384.         if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */
  385.  
  386.         tab_prefixof(code) = (unsigned short)oldcode;
  387.         tab_suffixof(code) = (char_type)finchar;
  388.         free_ent = code+1;
  389.         } 
  390.         oldcode = incode;    /* Remember previous code.    */
  391.     }
  392.     } while (rsize != 0);
  393.     
  394.     if (!test && outpos > 0) {
  395.     write_buf(out, (char*)outbuf, outpos);
  396.     bytes_out += (ulg)outpos;
  397.     }
  398.     return OK;
  399. }
  400.